<?php


namespace App\Middleware;


use App\Constants\CoContext;
use App\Constants\ContextKey;
use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Model\AdminUser;
use App\Utils\Casbin;
use App\Utils\Jwt;
use Hyperf\Utils\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class AdminAuthMiddleware implements MiddlewareInterface
{

    /**
     * @var Casbin
     */
    protected $adminCasbinInstance;

    public function __construct()
    {
        $this->adminCasbinInstance = new Casbin(config('casbin.admin'));
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $adminUser = $this->verifyToken($request);

        $this->checkPermission($request, $adminUser);

        return $handler->handle($request);
    }

    /**
     * @param ServerRequestInterface $request
     * @return \Hyperf\Database\Model\Builder|\Hyperf\Database\Model\Model|object
     */
    public function verifyToken(\Hyperf\HttpMessage\Server\Request &$request): AdminUser
    {
        if ($request->hasHeader('authorization')) {
            $token = $request->getHeaderLine('authorization');
        } else {
            // query 参数里面的token
            $queries = $request->getQueryParams();
            if (!isset($queries['authorization'])) {
                throw new BusinessException(ErrorCode::UNAUTHORIZED);
            }
            // 获取到以后过滤query中token
            $token = $queries['authorization'];
            unset($queries['authorization']);
            $request = $request->withQueryParams($queries);
        }

        $verifiedToken = Jwt::verify($token);

        $adminUserId = $verifiedToken->getClaim('id');

        $adminUser = AdminUser::query()->where('id', $adminUserId)->first();

        if (null == $adminUser) {
            throw new BusinessException(ErrorCode::ADMIN_USER_NOT_FOUND);
        }

        Context::set(ContextKey::ADMIN_USER, $adminUser);

        return $adminUser;
    }

    public function checkPermission(ServerRequestInterface $request, AdminUser $adminUser)
    {
//        if ('local' != \env('APP_ENV')) {
//            return true;
//        }
        return;
        $userId = $adminUser->id;

        $path = $request->getUri()->getPath();

        $method = $request->getMethod();

        $can = $this->adminCasbinInstance->can($userId, $path, $method);

        if (!$can) {
            throw new BusinessException(ErrorCode::PERMISSION_DENIED);
        }
    }
}